﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace SpiralClock
{
    /// <summary>
    /// Interaction logic for SClock.xaml
    /// </summary>
    public partial class SClock : UserControl
    {
        public SClock()
        {
            InitializeComponent();
            LayoutRoot.LayoutUpdated += new EventHandler(LayoutRoot_LayoutUpdated);

            Initialize();
        }



        const double r1 = 22.52;
        const double r2 = 18.00;

        const double a = 4 * r2 - 3 * r1;
        const double b = 2 * (r2 - r1) / Math.PI;

        const double x0 = 50.5;
        const double y0 = 45.5;




        void LayoutRoot_LayoutUpdated(object sender, EventArgs e)
        {
            el.Height = scale*5;
            el.Width = scale*5;
            double angle = CalculateAngle(DateTime.Now);
            Point initPos = CalculatePosition(angle);
            
            TransformGroup trg = GetPointTransform();
            Point newPos = trg.Transform(initPos);
            el.SetValue(Canvas.LeftProperty, newPos.X - el.ActualWidth / 2);
            el.SetValue(Canvas.BottomProperty, newPos.Y - el.ActualHeight / 2);

            el.ToolTip = DateTime.Now.ToShortTimeString();
            int i = 0;
            foreach (TextBlock textb in hourLabels)
            {
                Point pos = hourPositions[i];

                Point new_pos = trg.Transform(pos);
                textb.FontSize = scale * 5;
                textb.SetValue(Canvas.LeftProperty, new_pos.X - textb.ActualWidth / 2);
                textb.SetValue(Canvas.BottomProperty, new_pos.Y - textb.ActualHeight / 2);

                i++;

            }




        }





        Ellipse el = new Ellipse();
        double scale = 1;

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {

            el.Height = 5;
            el.Width = 5;


            el.Fill = new SolidColorBrush(Color.FromArgb(100, 0, 0, 0));
            el.Stroke = Brushes.Black;

            el.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
            el.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
            Point initPos = CalculatePosition(-7 * Math.PI / 4);
            Point newPos = TransformPoint(initPos);

            canvas.Children.Add(el);
        }

        Point TransformPoint(Point inputPoint)
        {

            double height = LayoutRoot.ActualHeight;
            double width = LayoutRoot.ActualWidth;

            double widthRatio = width / 90.90;
            double heightRatio = height / 100.00;
            double minRatio = Math.Min(widthRatio, heightRatio);
            double minDimension = Math.Min(height, width);
            double scale = 1.0;

           


            if (minRatio == widthRatio)
                scale = width / 90.9;
            else 
                scale = height / 100;


            this.scale = scale;

            double horizontalTranslation = Math.Abs(width - scale*90.9) / 2;
            double verticalTranslation = Math.Abs(height - scale*100) / 2;

            ScaleTransform scaleTransform = new ScaleTransform(scale, scale);
            TranslateTransform translateTransform = new TranslateTransform(horizontalTranslation, verticalTranslation);

            Point p = inputPoint;
            p = scaleTransform.Transform(p);
            p = translateTransform.Transform(p);

            return p;
        }



        TransformGroup GetPointTransform()
        {

            double height = LayoutRoot.ActualHeight;
            double width = LayoutRoot.ActualWidth;

            double widthRatio = width / 90.90;
            double heightRatio = height / 100.00;
            double minRatio = Math.Min(widthRatio, heightRatio);
            double minDimension = Math.Min(height, width);
            double scale = 1.0;




            if (minRatio == widthRatio)
                scale = width / 90.9;
            else
                scale = height / 100;


            this.scale = scale;

            double horizontalTranslation = Math.Abs(width - scale * 90.9) / 2;
            double verticalTranslation = Math.Abs(height - scale * 100) / 2;

            ScaleTransform scaleTransform = new ScaleTransform(scale, scale);
            TranslateTransform translateTransform = new TranslateTransform(horizontalTranslation, verticalTranslation);

            TransformGroup trg = new TransformGroup();
            trg.Children.Add(scaleTransform);
            trg.Children.Add(translateTransform);
            return trg;



        }



        double CalculateAngle(DateTime time)
        {
            TimeSpan timeOfDay = time.TimeOfDay;

            return CalculateAngle(timeOfDay);

        }
        double CalculateAngle(TimeSpan time)
        {
            TimeSpan timeOfDay = time;

            double secondsFactor = (double)(-timeOfDay.TotalSeconds) * (Math.PI / 6) / 3600;

            return -3 * Math.PI / 2 + secondsFactor;

        }

        List<Point> hourPositions = new List<Point>();

        Point CalculatePosition(double θ)
        {
            double r = a + b * θ;

            double x = r * Math.Cos(θ) + x0;
            double y = r * Math.Sin(θ) + y0;

            return new Point(x, y);




        }


        List<TextBlock> hourLabels = new List<TextBlock>();

        void Initialize()
        {
            for (int i = 0; i <= 23; i++)
            {
                TimeSpan ts = new TimeSpan(i, 0, 0);

                double angle = CalculateAngle(ts);

                TextBlock tb = new TextBlock();
                tb.FontSize = 10 * scale;
                tb.Foreground = new SolidColorBrush(Color.FromArgb(50, 0, 0, 0));
                Point pos = CalculatePosition(angle);

                canvas.Children.Add(tb);

                hourPositions.Add(pos);
     

                tb.Text = i.ToString();


                hourLabels.Add(tb);
            }



        }
    }
}
